using System.Diagnostics;
using System.Data;
using System.Collections;
using Microsoft.VisualBasic;
using System.Collections.Generic;
using System;
using System.Text.RegularExpressions;
using Microsoft.VisualBasic.CompilerServices;

namespace Dimok.Web.UI {

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>	Grid view search. </summary>
	///
	/// <remarks>	Dimon, 12/21/2010. </remarks>
	////////////////////////////////////////////////////////////////////////////////////////////////////

	public class GridViewSearch {

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Bitfield of flags for specifying SearchTypes. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		[Flags]
		public enum SearchTypes {
			None = 0,
			Numeric = 1,
			Address = 2,
			Name = 4,
			Linq = 128
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Normalize search. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="fieldName">	Name of the field. </param>
		/// <param name="text">				The text. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static string NormalizeSearch(string fieldName, string text) {
			return NormalizeSearch(fieldName, text, SearchTypes.None);
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Normalize search. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="fieldName">	Name of the field. </param>
		/// <param name="text">				The text. </param>
		/// <param name="searchType">	Type of the search. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static string NormalizeSearch(string fieldName, string text, SearchTypes searchType) {
			if(searchType == SearchTypes.None) {
				if(StringType.StrLike(fieldName.ToLower(), "last*name", CompareMethod.Binary) || StringType.StrLike(fieldName.ToLower(), "first*name", CompareMethod.Binary)) {
					searchType = SearchTypes.Name;
				} else if(StringType.StrLike(fieldName.ToLower(), "*street*", CompareMethod.Binary) || StringType.StrLike(fieldName.ToLower(), "*address*", CompareMethod.Binary)) {
					searchType = SearchTypes.Address;
				}
			}
			return NormalizeSearch(text, searchType);
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Normalize search. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="text">	The text. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static string NormalizeSearch(string text) {
			return NormalizeSearch(text, SearchTypes.None);
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Normalize search. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="text">				The text. </param>
		/// <param name="searchType">	Type of the search. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static string NormalizeSearch(string text, SearchTypes searchType) {
			if(searchType == SearchTypes.None && System.Text.RegularExpressions.Regex.IsMatch(text, "^\\d+$")) {
				searchType = SearchTypes.Numeric;
			}
			switch(searchType) {
				case SearchTypes.Address:

					text = System.Text.RegularExpressions.Regex.Replace(text, "[^0-9]+", "%");
					break;
				case SearchTypes.Name:

					text = System.Text.RegularExpressions.Regex.Replace(text, "[^\\w]+", "%");
					break;
			}
			return text;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Builds a filter. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="fieldName">	Name of the field. </param>
		/// <param name="text">				The text. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static string BuildFilter(string fieldName, string text) {
			return BuildFilter(fieldName, text, SearchTypes.None);
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Builds a filter. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <exception cref="Exception">	Thrown when exception. </exception>
		///
		/// <param name="fieldName">	Name of the field. </param>
		/// <param name="text">				The text. </param>
		/// <param name="searchType">	Type of the search. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static string BuildFilter(string fieldName, string text, SearchTypes searchType) {
			try {
				bool isLinq = (searchType & SearchTypes.Linq) == SearchTypes.Linq;
				string q = isLinq ? "\"" : "\'";
				string filterText = text;
				string oper = "LIKE";
				string perc = "%";
				string quota_o = q;
				string quota_c = quota_o;
				string not = "";
				Regex reNot = new Regex("^!\\s*");
				if( reNot.IsMatch(filterText) ) {
					not = " NOT ";
					filterText = reNot.Replace(filterText,"");
				}
				if(searchType == SearchTypes.Numeric) {
					perc = "";
					quota_c = quota_o = "";
					oper = "=";
				}
				if(filterText.IndexOf("%") >= 0) {
					perc = "";
					quota_c = quota_o = q;
					oper = "LIKE";
				}
				if (Regex.IsMatch(filterText, "^'.+'$")) {
					oper = "=";
					perc = "";
					quota_o = quota_c = "";
					if (isLinq) filterText = q + filterText.Trim('\'') + q;
				}
				if(Regex.IsMatch(filterText, "^(<|>|=)",RegexOptions.IgnoreCase)) {
					string[] a = Regex.Split(filterText, @"(==\s*|><\s*|<>\s*|>=\s*|<=\s*|>\s*|<\s*|=\s*)", RegexOptions.IgnoreCase);
					oper = a[1].Trim();
					filterText = a[2];
					//quota_o = quota_c = "";
					perc = "";
					switch (oper) {
						case "><": oper = "BETWEEN"; quota_o = quota_c = ""; break;
						case "==":
							oper = "IN"; quota_o = "("; quota_c = ")"; break;
						default:
							if (!Microsoft.VisualBasic.Information.IsNumeric(filterText) && !Regex.IsMatch(filterText, "^'.+'$"))
								quota_c = quota_o = q;
							break;
					}
				}
				if (oper == "LIKE")
					filterText = filterText.Replace('@', '_').Replace("'", "''").Replace("[", "[[]");
				//filterText = NormalizeSearch(fieldName, filterText, searchType);
				return string.Format("[{1}]{0}{2} {3}{4}{5}{6}{7}", not, fieldName, oper, quota_o, perc, filterText, perc, quota_c).Replace("%%", "%");
			} catch(Exception ex) {
				throw (new Exception("", ex));
			}
		}

	}

}
